#include "Device.hpp"
#include "Camera.hpp"
#include "Engine/Debug/Logger.hpp"
#include "Engine/Renderer/Text.hpp"

namespace red{
	Device::Device() : mInitialized(false), mFPSText(0){

	}

	Device::~Device(){
		#ifdef _DEBUG
		LogManager::Kill();
		#endif
	}

	void Device::Init(){
		// Initialisation of LogManager for debug purposes
		#ifdef _DEBUG
		LogManager::Call().Init();
		#endif

		// Initialize the MainWindow and Launch it
		mWindow.Init();

		// Initialize the OpenGL Renderer
		mRenderer.Init(this);

		// Initialize inputs
		mInputs.Init(mWindow);

		// Initialize SceneManager
		mScene.Init(this);

		// Reset clock and get the current time
		mDeviceClock.Reset();
		mFPSClock.Reset();
		mDeviceStartTime = static_cast<f32>(GetSystemTime());

		// FPS Showing Text
		mFPSText = mScene.AddText("", Vector2I(10,24), Color::Black, 12);

		mInitialized = true;
	}

	bool Device::Run(){
		if(!mInitialized) return false;

		// Frame Elapsed Time
		mFrameTime = mDeviceClock.GetElapsedTime();
		mDeviceClock.Reset();

		// FPS Counter
		if(mFPSClock.GetElapsedTime() > 1.f)
			if(mFPSText->IsEnabled()){
				mFPSText->SetText(String("FPS: ")+(1.f/mFrameTime));
				mFPSClock.Reset();
			}

		// Event handling
		sf::Event evt;
		while(mWindow.GetWindow().GetEvent(evt)){
			if(!ProcessEvent(evt))
				return false;
		}

		// Inputs handling
		HandleInputs();


		return true;
	}

	bool Device::ProcessEvent(sf::Event &pEvent){
		// General
		if(pEvent.Type == sf::Event::Closed || (pEvent.Type == sf::Event::KeyPressed && pEvent.Key.Code == sf::Key::Escape))
			return false;

		// Camera
		mScene.GetActiveCamera()->OnEvent(pEvent);


		return true;
	}

	void Device::HandleInputs(){
		// Camera
		mScene.HandleCameraInputs();
	}

	void Device::BeginRender(){
		mRenderer.BeginScene();
	}

	void Device::EndRender(){
		mWindow.GetWindow().Display();
	}

	void Device::ShowFps(bool pVal){
		mFPSText->Enable(pVal);
	}
}